package utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.net.*;
import java.util.Enumeration;

public class HttpContextUtils {
    private static final Logger log = LoggerFactory.getLogger(HttpContextUtils.class);

    public static HttpServletRequest getRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                    .getRequest();
        }else {
            return null;
        }
    }

    /**
     * @Description:  获取IP地址的方法
     * @Param: []
     * @return: java.lang.String
     * @Author: XQD
     * @Date:2021/3/9 11:22
     */
    public static String getIpAddress() {
        HttpServletRequest request = getRequest();
        if (request == null){
            return "127.0.0.1";
        }
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
            ip = request.getRemoteAddr();
            if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)){
                InetAddress inetAddress = null;
                try {
                    inetAddress = InetAddress.getLocalHost();
                }catch (UnknownHostException e){
                    log.error(e.getMessage());
                }
                // 获取本机真正的ip地址
                ip = inetAddress.getHostAddress();
            }
        }
        // 2023-1-12 新增
        /*try {
            ip = getFirstNonLoopbackAddress( true, false).getHostAddress();

        }catch (SocketException e) {
            log.error(e.getMessage());
        }*/
        String[] ips = ip.split(",");
        for (String i : ips){
            System.out.println("-------ips:-------"+i);
        }
        ip = ips[0];
        log.info("ip地址-----:{}",ip);

//        getAllIpAddress(); // 获取所有ip地址
//        getIpAddrByName("WAN Miniport (IPv6)");
        return ip;
    }

    /**
     * 获取所有的ip地址-通用
     */
    public static void getAllIpAddress() {
        try {
            //get all network interface
            Enumeration<NetworkInterface> allNetworkInterfaces =
                    NetworkInterface.getNetworkInterfaces();
            NetworkInterface networkInterface = null;

            //check if there are more than one network interface
            while (allNetworkInterfaces.hasMoreElements()) {
                //get next network interface
                networkInterface = allNetworkInterfaces.nextElement();
                //output interface's name
                System.out.println("network interface: " +
                        networkInterface.getDisplayName());

                //get all ip address that bound to this network interface
                Enumeration<InetAddress> allInetAddress =
                        networkInterface.getInetAddresses();

                InetAddress ipAddress = null;

                //check if there are more than one ip addresses
                //band to one network interface
                while (allInetAddress.hasMoreElements()) {
                    //get next ip address
                    ipAddress = allInetAddress.nextElement();
                    if (ipAddress != null && ipAddress instanceof Inet4Address) {
                        System.out.println("ip address: " +
                                ipAddress.getHostAddress());
                    }
                }
            }

        } catch (SocketException e) {
            e.printStackTrace();
        }
    }//end method getAllIpAddress

    public static boolean getIpAddrByName(String networkInterfaceName) {
        try {
            //get network interface by name
            NetworkInterface networkInterface =
                    NetworkInterface.getByName(networkInterfaceName);
            if (networkInterface == null) {
                return false;
            }
            System.out.println("network interface: " +
                    networkInterface.getDisplayName());

            InetAddress ipAddress = null;
            //get all ip addresses band to this interface
            Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();

            while (addresses.hasMoreElements()) {
                ipAddress = addresses.nextElement();

                if (ipAddress != null && ipAddress instanceof Inet4Address) {
                    System.out.println("ip address: " +
                            ipAddress.getHostAddress());
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }

        return true;
    }// end method getIpAddrByName

    /**
     * 获取ipv4/ipv6
     * @param preferIpv4
     * @param preferIPv6
     * @return
     * @throws SocketException
     */
    public static InetAddress getFirstNonLoopbackAddress(boolean preferIpv4, boolean preferIPv6) throws SocketException {
        Enumeration en = NetworkInterface.getNetworkInterfaces();
        while (en.hasMoreElements()) {
            NetworkInterface i = (NetworkInterface) en.nextElement();
            for (Enumeration en2 = i.getInetAddresses(); en2.hasMoreElements();) {
                InetAddress addr = (InetAddress) en2.nextElement();
                if (!addr.isLoopbackAddress()) {
                    if (addr instanceof Inet4Address) {
                        if (preferIPv6) {
                            continue;
                        }
                        return addr;
                    }
                    if (addr instanceof Inet6Address) {
                        if (preferIpv4) {
                            continue;
                        }
                        return addr;
                    }
                }
            }
        }
        return null;
    }
}
